package com.wfy.common.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.codec.binary.Base64;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Hashtable;

/**
 * 二维码工具
 */
public class ZxingHandler {

    private static final int DEFAULT_WIDTH = 200;
    private static final int DEFAULT_HEIGHT = 200;
    private static final String DEFAULT_FORMAT = "PNG";

    /**
     * 生成二维码
     */
    public static void generateCode2(String content, HttpServletRequest request, HttpServletResponse response) {
        generateCode2(content, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, request, response);
    }

    public static void generateCode2(String content, int width, int height, HttpServletRequest request, HttpServletResponse response) {
        generateCode2(content, width, height, DEFAULT_FORMAT, request, response);
    }

    /**
     * 生成二维码
     *
     * @param content  二维码内容
     * @param width    width
     * @param height   height
     * @param format   文件格式 png等
     * @param request
     * @param response
     */
    public static void generateCode2(String content, int width, int height, String format, HttpServletRequest request, HttpServletResponse response) {
        HttpServletResponse resp = (HttpServletResponse) response;
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        // 指定编码格式
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
                    BarcodeFormat.QR_CODE, width, height, hints);
            request.setCharacterEncoding("utf-8");
            resp.setCharacterEncoding("utf-8");
            MatrixToImageWriter.writeToStream(bitMatrix, format, resp.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String generateCode2(String content) {
        ByteArrayOutputStream bos = null;

        MultiFormatWriter formatWriter = new MultiFormatWriter();

        Hashtable<EncodeHintType, Object> param = new Hashtable<>();
        param.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q);
        param.put(EncodeHintType.CHARACTER_SET, "utf-8");
        param.put(EncodeHintType.MARGIN, 0);

        try {
            BitMatrix bitMatrix = formatWriter
                    .encode(content, BarcodeFormat.QR_CODE, DEFAULT_WIDTH, DEFAULT_HEIGHT, param);
            // 1.1去白边
            int[] rec = bitMatrix.getEnclosingRectangle();
            int resWidth = rec[2] + 1;
            int resHeight = rec[3] + 1;
            BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
            resMatrix.clear();
            for (int i = 0; i < resWidth; i++) {
                for (int j = 0; j < resHeight; j++) {
                    if (bitMatrix.get(i + rec[0], j + rec[1])) {
                        resMatrix.set(i, j);
                    }
                }
            }
            int width1 = resMatrix.getWidth();
            int height1 = resMatrix.getHeight();
            BufferedImage qrcode = new BufferedImage(width1, height1, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < width1; x++) {
                for (int y = 0; y < height1; y++) {
                    qrcode.setRGB(x, y, resMatrix.get(x, y) == true ? Color.BLACK.getRGB() : Color.WHITE
                            .getRGB());
                }
            }

            bos = new ByteArrayOutputStream();
            ImageIO.write(qrcode, "png", bos);

            String img = StringUtils.deleteWhitespace(Base64.encodeBase64String(bos.toByteArray()));
            return String.format("data:image/png;base64,%s", img);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                }
            }
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        String str = ZxingHandler.generateCode2("http://www.smartfactorycloud.cn:80/f/mp/user/scancode?officeId=3fe0663cd82746f0988ab02adaa6aa6f&userId=015c128639674d0fb056fb6b023e6a5d");
        System.out.println(str);
    }

}